import { Fragment, PureComponent } from 'react';
import {
  Card,
  Image,
  Divider,
  Popconfirm,
  Form,
  Row,
  Col,
  Input,
  Button,
  Radio,
  Modal,
  Avatar,
  Upload,
  message,
  Select,
  Switch,
  Progress,
  Tag
} from 'antd';
import React from 'react';
import Icon, { UploadOutlined } from '@ant-design/icons';
import { connect } from 'umi';
import { formatMessage } from '@@/plugin-locale/localeExports';
import ProTable from '@ant-design/pro-table';
import styles from '../common.less';
import TextArea from 'antd/es/input/TextArea';
import { hasPermission, nopermission } from '@/hasPermission';
import { deleteUser, updateUserInfo } from '@/pages/UserList/service';

const { Option } = Select;

function beforeUpload(file) {
  if (!hasPermission('admin:update')) {
    nopermission();
    return false;
  }
  let isImage =
    file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif';
  if (!isImage) {
    message.error('请上传jpg或png格式文件!');
    return false;
  }
  let isst10M = file.size / 1024 / 1024 < 10;
  if (!isst10M) {
    message.error('文件过大！请重新上传');
  }
  const isNotEmpty = file.size > 0;
  if (!isNotEmpty) {
    message.error('文件为空！请重新上传');
  }
  return isImage && isst10M && isNotEmpty;
}

class UserList extends PureComponent {
  state = {
    formValues: {},
    updateFormValues: {},
    currentPage: 1,
    pageSize: 10,
    modalVisible: false,
    avatarLoading: false,
    num: 0,
    percent: 0,
    avatarKey: 'updateAvatar',
  };

  columns = [
    {
      title: formatMessage({ id: 'app.userList.loginName' }),
      dataIndex: 'loginName',
      align: 'center',
    },
    {
      title: formatMessage({ id: 'app.userList.avatar' }),
      dataIndex: 'avatar',
      width: '100px',
      align: 'center',
      render: (val) => <Image style={{ width: '100%' }} src={val} />,
    },
    {
      title: formatMessage({ id: 'app.userList.sex' }),
      align: 'center',
      dataIndex: 'sex',
      width: 70,
    },
    {
      title: formatMessage({ id: 'app.userList.age' }),
      align: 'center',
      dataIndex: 'age',
      width: 70,
    },
    {
      title: formatMessage({ id: 'app.userList.address' }),
      align: 'center',
      dataIndex: 'address',
    },
    {
      title: formatMessage({ id: 'app.userList.email' }),
      align: 'center',
      dataIndex: 'email',
    },
    {
      title: formatMessage({ id: 'app.userList.phone' }),
      align: 'center',
      dataIndex: 'phone',
      width: 110,
    },
    {
      title: formatMessage({ id: 'app.userList.roleName' }),
      align: 'center',
      dataIndex: 'roleName',
      render: (val) => <Tag color={val == 'ROLE_ADMIN' ? 'gold' : (val == 'ROLE_TESTADMIN' ? 'volcano' : 'blue')}>{val == 'ROLE_ADMIN' ? '超级管理员' : (val == 'ROLE_TESTADMIN' ? '测试管理员' : '普通用户')}</Tag>,
    },
    {
      title: formatMessage({ id: 'app.userList.createTime' }),
      align: 'center',
      dataIndex: 'createTime',
      width: 120,
    },
    {
      title: formatMessage({ id: 'app.userList.lastLoginTime' }),
      align: 'center',
      dataIndex: 'lastLoginTime',
      width: 120,
    },
    {
      title: formatMessage({ id: 'app.common.operate' }),
      align: 'center',
      width: '100px',
      render: (text, record) => (
        <Fragment>
          <a onClick={() => this.handleModalVisible(true, record)}>
            <Icon type="edit" />
            {formatMessage({ id: 'app.common.edit' })}
          </a>
          {record.roleName != 'ROLE_ADMIN' && [
            <Divider type="vertical" />,
            <Popconfirm
              title={formatMessage({ id: 'app.common.confirm-delete' })}
              onConfirm={() => this.deleteUser(record.id)}
            >
              <a>
                <Icon type="delete" />
                {formatMessage({ id: 'app.common.delete' })}
              </a>
            </Popconfirm>,
          ]}
        </Fragment>
      ),
    },
  ];

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'userList/fetch',
    });
    this.formRef = React.createRef();
    this.formRef2 = React.createRef();
  }

  handleBasicTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const { formValues } = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = { ...obj };
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      ...formValues,
      ...filters,
      currentPage: pagination.current,
      pageSize: pagination.pageSize,
    };
    if (sorter.field && sorter.order) {
      params.sorter = `${sorter.field}_${sorter.order}`;
    }
    this.setState({ currentPage: pagination.current, pageSize: pagination.pageSize });
    dispatch({
      type: 'userList/fetch',
      payload: params,
    });
  };

  handleSearch = (e) => {
    const { dispatch } = this.props;
    const values = {
      ...e,
    };
    this.setState({
      formValues: values,
    });
    if (e == null) {
      values.currentPage = this.state.currentPage;
      values.pageSize = this.state.pageSize;
    } else {
      values.currentPage = 1;
      values.pageSize = 10;
    }
    dispatch({
      type: 'userList/fetch',
      payload: values,
    });
  };

  handleFormReset = () => {
    const { dispatch } = this.props;
    this.formRef.current.resetFields();
    this.setState({
      formValues: {},
      currentPage: 1,
      pageSize: 10,
    });
    dispatch({
      type: 'userList/fetch',
    });
  };

  handleModalVisible = (flag, value) => {
    this.setState({
      modalVisible: !!flag,
      updateFormValues: value || {},
    });
  };

  handleChange = (info) => {
    const { avatarKey, num } = this.state;
    this.setState({ percent: info.file.percent });
    if (info.file.status == 'uploading' && num == 0) {
      this.setState({
        num: 1,
        avatarLoading: true,
      });
    }
    const fileList = info.fileList;
    this.setState({ fileList });
    if (info.file.status === 'done') {
      let res = info.file.response;
      if (res.status == 200) {
        this.setState({
          updateFormValues: {
            ...this.state.updateFormValues,
            avatar: res.data,
          },
        });
        message.success({ content: '上传成功！', avatarKey, duration: 2 });
      }else {
        message.error({ content: res.message, avatarKey, duration: 2 });
      }
      this.setState({
        num: 0,
        avatarLoading: false,
      });
    }
  };

  handleUpdate = () => {
    const { updateFormValues } = this.state;
    if (!hasPermission('admin:update')) {
      nopermission();
      return;
    }
    let values = this.formRef2.current.getFieldsValue();
    if (values.loginName == updateFormValues.loginName) {
      values.loginName = '';
    }
    values.avatar = null;
    values.lock = values.lock ? 1 : 0;
    values.tags = values.tags ? (values.tags.length > 0 ? values.tags.toString() : '') : '';
    values.roleId =
      (values.roleName &&
        (values.roleName == 'ROLE_ADMIN' ? 1 : values.roleName == 'ROLE_TESTADMIN' ? 3 : 2)) ||
      null;
    updateUserInfo({ ...values }).then((res) => {
      if (res.status == 200) {
        message.success('修改成功！');
        this.handleModalVisible();
        this.handleSearch();
      }
    });
  };

  deleteUser = (id) => {
    if (!hasPermission('admin:delete')) {
      nopermission();
      return;
    }
    deleteUser({ id: id }).then((res) => {
      if (res.status == 200) {
        message.success('删除成功！');
        this.handleSearch();
      }
    });
  };

  renderSimpleForm() {
    return (
      <Form ref={this.formRef} onFinish={this.handleSearch}>
        <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
          <Col md={7} sm={24} offset={1}>
            <Form.Item label={formatMessage({ id: 'app.userList.loginName' })} name="loginName">
              <Input placeholder={formatMessage({ id: 'app.userList.loginName' })} />
            </Form.Item>
          </Col>
          <Col md={7} sm={24}>
            <Form.Item label={formatMessage({ id: 'app.userList.roleName' })} name="roleName">
              <Radio.Group>
                <Radio.Button value="ROLE_USER">普通用户</Radio.Button>
                <Radio.Button value="ROLE_ADMIN">超级管理员</Radio.Button>
                <Radio.Button value="ROLE_TESTADMIN">测试管理员</Radio.Button>
              </Radio.Group>
            </Form.Item>
          </Col>
          <Col md={6} sm={24}>
            <span className={styles.submitButtons}>
              <Button style={{ marginLeft: 8 }} type="primary" htmlType="submit">
                <Icon type="search" />
                {formatMessage({ id: 'app.common.query' })}
              </Button>
              <Button style={{ marginLeft: 8 }} onClick={this.handleFormReset} type="primary">
                <Icon type="reload" />
                {formatMessage({ id: 'app.common.reset' })}
              </Button>
            </span>
          </Col>
        </Row>
      </Form>
    );
  }

  renderForm() {
    return this.renderSimpleForm();
  }

  renderModalContent = (values) => {
    const { avatarLoading, percent } = this.state;

    return (
      <Form ref={this.formRef2}>
        <Row>
          <Col span={12}>
            <Row>
              <Col span={8}>
                <Form.Item
                  initialValue={values.avatar}
                  label={formatMessage({ id: 'app.userList.avatar' })}
                  name="avatar"
                >
                  <Avatar size="large" src={values.avatar} />
                  {avatarLoading && <Progress percent={percent} style={{ opacity: 0.8 }} />}
                </Form.Item>
              </Col>
              <Col span={16}>
                <Upload
                  name="file"
                  action="joker/minio/upload"
                  data={{
                    id: values.id,
                    table: 'USERS',
                  }}
                  headers={{
                    Authorization: 'Bearer ' + localStorage.getItem('token'),
                  }}
                  showUploadList={false}
                  accept="image/*"
                  beforeUpload={beforeUpload.bind(this)}
                  onChange={this.handleChange.bind(this)}
                >
                  <div style={{ width: '110px', textAlign: 'center' }}>
                    <Button>
                      <UploadOutlined />
                      {formatMessage({ id: 'app.userList.editAvatar' })}
                    </Button>
                  </div>
                </Upload>
              </Col>
            </Row>
          </Col>
          <Col span={12}>
            <Form.Item
              initialValue={values.loginName}
              label={formatMessage({ id: 'app.userList.loginName' })}
              name="loginName"
            >
              <Input
                style={{ width: '90%' }}
                placeholder={formatMessage({ id: 'app.userList.loginName' })}
              />
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={12}>
            <Form.Item
              initialValue={values.age}
              label={formatMessage({ id: 'app.userList.age' })}
              name="age"
            >
              <Input
                style={{ width: '90%' }}
                placeholder={formatMessage({ id: 'app.userList.age' })}
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              initialValue={values.sex}
              label={formatMessage({ id: 'app.userList.sex' })}
              name="sex"
            >
              <Select style={{ width: '90%' }}>
                <Option value="男">男</Option>
                <Option value="女">女</Option>
                <Option value="未知">未知</Option>
              </Select>
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={12}>
            <Form.Item
              initialValue={values.email}
              label={formatMessage({ id: 'app.userList.email' })}
              name="email"
            >
              <Input
                style={{ width: '90%' }}
                placeholder={formatMessage({ id: 'app.userList.email' })}
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              initialValue={values.phone}
              label={formatMessage({ id: 'app.userList.phone' })}
              name="phone"
            >
              <Input
                style={{ width: '90%' }}
                placeholder={formatMessage({ id: 'app.userList.phone' })}
              />
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <Form.Item
              initialValue={values.roleName}
              label={formatMessage({ id: 'app.userList.roleName' })}
              name="roleName"
            >
              <Radio.Group disabled={values.loginName == 'admin'}>
                <Radio.Button value="ROLE_USER">普通用户</Radio.Button>
                <Radio.Button value="ROLE_ADMIN">超级管理员</Radio.Button>
                <Radio.Button value="ROLE_TESTADMIN">测试管理员</Radio.Button>
              </Radio.Group>
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={12}>
            <Form.Item
              initialValue={values.lock ? values.lock : 0}
              label={formatMessage({ id: 'app.userList.lock' })}
              name="lock"
            >
              <Switch
                disabled={values.loginName == 'admin'}
                checkedChildren="已锁定"
                unCheckedChildren="未锁定"
                defaultChecked={values.lock == 1}
              />
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={12}>
            <Form.Item
              initialValue={values.backupEmail}
              label={formatMessage({ id: 'app.userList.backupEmail' })}
              name="backupEmail"
            >
              <Input
                style={{ width: '90%' }}
                placeholder={formatMessage({ id: 'app.userList.backupEmail' })}
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item
              initialValue={values.backupPhone}
              label={formatMessage({ id: 'app.userList.backupPhone' })}
              name="backupPhone"
            >
              <Input
                style={{ width: '90%' }}
                placeholder={formatMessage({ id: 'app.userList.backupPhone' })}
              />
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <Form.Item
              initialValue={values.tags ? values.tags.split(',') : []}
              label={formatMessage({ id: 'app.userList.tags' })}
              name="tags"
            >
              <Select mode="tags" style={{ width: '100%' }} placeholder="请输入标签"></Select>
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <Form.Item
              initialValue={values.signature}
              label={formatMessage({ id: 'app.userList.signature' })}
              name="signature"
            >
              <TextArea placeholder={formatMessage({ id: 'app.userList.signature' })} />
            </Form.Item>
          </Col>
        </Row>
        <Row style={{ display: 'none' }}>
          <Col span={24}>
            <Form.Item initialValue={values.id} name="id">
              <Input hidden={true} />
            </Form.Item>
          </Col>
        </Row>
      </Form>
    );
  };
  render() {
    const {
      userList: { data },
      loading,
    } = this.props;
    const { modalVisible, updateFormValues } = this.state;
    return (
      <>
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListForm}>{this.renderForm()}</div>
            <ProTable
              bordered={true}
              search={false}
              rowKey={(record) => record.id}
              loading={loading}
              dataSource={data ? data.list : []}
              pagination={data ? data.pagination : {}}
              columns={this.columns}
              onChange={this.handleBasicTableChange}
              options={{
                density: true,
                reload: () => {
                  this.handleSearch();
                },
                fullScreen: true,
                setting: true,
              }}
            />
          </div>
        </Card>
        {modalVisible && Object.keys(updateFormValues).length > 0 && (
          <Modal
            destroyOnClose
            width={650}
            bodyStyle={{ paddingBottom: 0, paddingTop: 20 }}
            title={formatMessage({ id: 'app.userList.editUser' })}
            visible={modalVisible}
            onOk={this.handleUpdate}
            onCancel={() => this.handleModalVisible(false, null)}
            afterClose={() => this.handleModalVisible()}
          >
            {this.renderModalContent(updateFormValues)}
          </Modal>
        )}
      </>
    );
  }
}

export default connect(({ userList, loading }) => ({
  userList,
  loading: loading.effects['userList/fetch'],
}))(UserList);
